import java.awt.Desktop;
import java.awt.Event;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JEditorPane;
import javax.swing.event.HyperlinkEvent;
import javax.swing.event.HyperlinkListener;

import net.sf.stackwrap4j.entities.Reputation;
import net.sf.stackwrap4j.entities.User;
import net.sf.stackwrap4j.json.JSONException;
import net.sf.stackwrap4j.stackauth.entities.Site;

import org.joda.time.DateTime;

public class ReputationTab extends JEditorPane {

    private User user;
    private Site site;
    private List<Reputation> reps;

    private DateTime startDate, endDate;

    private RepEntry repDisp;

    private StackWrapDataAccess data;

    public ReputationTab(User u, String site, List<Reputation> reps) throws IOException,
            JSONException {
        super("text/html", "");
        data = new StackWrapDataAccess(StackWrapDataAccess.Key);
        this.user = u;
        this.site = data.getSiteFromName(site);
        this.reps = reps;
        setEditable(false);
        endDate = new DateTime(System.currentTimeMillis());
        startDate = endDate.minusMonths(3);
        addHyperlinkListener(linker);
        fillWithData();
    }

    public void setRange(DateTime start, DateTime end) {
        endDate = end;
        startDate = start;
        fillWithData();
        repaint();
    }

    private final void fillWithData() {
        repDisp = new RepEntry();
        int start = findStartIndex();
        int end = findEndIndex();
        for (int i = start; i < end; i++) {
            Reputation rep = reps.get(i);
            repDisp.addRep(rep);
        }
        String txt = repDisp.getText();
        setText(txt);
    }

    private int findStartIndex() {
        for (int i = 0; i < reps.size(); i++) {
            if (new DateTime(reps.get(i).getOnDate() * 1000).isAfter(startDate))
                return i;
        }
        return 0;
    }

    private int findEndIndex() {
        for (int i = reps.size() - 1; i >= 0; i--) {
            if (new DateTime(reps.get(i).getOnDate() * 1000).isBefore(endDate))
                return i;
        }
        return reps.size();
    }

    private class RepEntry {
        private List<Reputation> rep;

        public RepEntry() {
            rep = new ArrayList<Reputation>();
        }

        public void addRep(Reputation r) {
            rep.add(r);
        }

        public String getText() {
            String ret = "<span>Date    </span><span>Title       </span><span>Reputation</span><br />\n";
            for (Reputation r : rep) {
                ret += repToDate(r) + repToLink(r) + repToRepAmnt(r);
                ret += "<br />\n";
            }
            return ret;
        }

        private String repToRepAmnt(Reputation r) {
            String base = "<span>" + (r.getPositiveRep() - r.getNegativeRep()) + "</span>";
            return base;
        }

        private String repToLink(Reputation r) {
            String base = "<a href=\"POST_ADDR\">POST_TITLE</a>";
            String url = site.getSiteUrl() + "/questions/" + r.getPostId();
            return base.replace("POST_ADDR", url).replace("POST_TITLE", sanitize(r.getTitle()));
        }

        private String repToDate(Reputation r) {
            return "<span>" + new DateTime(r.getOnDate() * 1000).toString("MMM dd yyy") + "</span>";
        }

        private String sanitize(String txt) {
            String[] bad = { "<", ">" };
            String[] good = { "&lt;", "&gt;" };
            for (int i = 0; i < bad.length; i++) {
                txt = txt.replaceAll(bad[i], good[i]);
            }
            return txt;
        }
    }

    private HyperlinkListener linker = new HyperlinkListener() {

        @Override
        public void hyperlinkUpdate(HyperlinkEvent e) {
            if (e.getEventType() != HyperlinkEvent.EventType.ACTIVATED)
                return;
            Desktop d = Desktop.getDesktop();
            try {
                d.browse(e.getURL().toURI());
            } catch (IOException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            } catch (URISyntaxException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
        }
    };
}
